home *** CD-ROM | disk | FTP | other *** search
- #ifndef EXEC_TYPES_H
- #include <exec/types.h>
- #endif
-
- /************************************************************************/
-
- #include "AVL.h"
-
- /************************************************************************/
-
- static void
- Rotate_R (struct AVLTree *Tree, struct AVLNode *Node)
-
- {
- struct AVLNode *Left, *Right;
- struct AVLNode *Parent;
-
- Left = Node->Left;
- Right = Node->Right;
- Parent = Node->Parent;
- if (Parent)
- {
- if (Parent->Left == Node)
- {
- Parent->Left = Left;
- }
- else
- {
- Parent->Right = Left;
- }
- }
- else
- {
- Tree->Root = Left;
- }
-
- Left->Parent = Parent;
-
- if ((Node->Left = Left->Right))
- Left->Right->Parent = Node;
-
- Left->Right = Node;
- Node->Parent = Left;
- }
-
- /************************************************************************/
-
- static void
- Rotate_L (struct AVLTree *Tree, struct AVLNode *Node)
-
- {
- struct AVLNode *Left, *Right;
- struct AVLNode *Parent;
-
- Left = Node->Left;
- Right = Node->Right;
- Parent = Node->Parent;
- if (Parent)
- {
- if (Parent->Left == Node)
- {
- Parent->Left = Right;
- }
- else
- {
- Parent->Right = Right;
- }
- }
- else
- {
- Tree->Root = Right;
- }
-
- Right->Parent = Parent;
-
- if ((Node->Right = Right->Left))
- Right->Left->Parent = Node;
-
- Right->Left = Node;
- Node->Parent = Right;
- }
-
- /************************************************************************/
- /* */
- /* Insert a node into a tree. */
- /* If a node with the same key already exists, return it. */
- /* Return NULL if successfull. */
- /* */
- /************************************************************************/
-
- struct AVLNode *
- AVL_InsertNode (struct AVLTree *Tree, struct AVLNode *Node)
-
- {
- struct AVLNode *CurrentNode, *Parent;
- int CompareResult; /* never used unitialized */
-
- /* Step 1: Find place where to insert node */
- CurrentNode = Tree->Root;
- Parent = NULL;
- while (CurrentNode)
- {
- Parent = CurrentNode;
- CompareResult = Tree->CompareNodes (CurrentNode, Node);
- if (CompareResult > 0)
- {
- CurrentNode = CurrentNode->Left;
- }
- else if (CompareResult < 0)
- {
- CurrentNode = CurrentNode->Right;
- }
- else
- {
- return CurrentNode;
- }
- }
-
- /* Step 2: Link node into tree */
- Node->Left = Node->Right = NULL;
- Node->Balance = 0;
- Node->Parent = Parent;
- if (Parent)
- {
- if (CompareResult > 0)
- {
- Parent->Left = Node;
- }
- else
- {
- Parent->Right = Node;
- }
- }
- else
- {
- Tree->Root = Node;
- }
-
- /* Step 3: Balance tree */
- while (Parent)
- {
- if (Parent->Left == Node)
- {
- switch (Parent->Balance)
- {
- case -1:
- if (Node->Balance == -1)
- {
- Parent->Balance = 0;
- Node->Balance = 0;
- }
- else
- {
- Parent->Balance = (Node->Right->Balance == -1);
- Node->Balance = -(Node->Right->Balance == 1);
- Node->Right->Balance = 0;
- Rotate_L (Tree, Node);
- }
- Rotate_R (Tree, Parent);
- return NULL;
-
- case 0:
- Parent->Balance = -1;
- Node = Parent;
- Parent = Node->Parent;
- break;
-
- case +1:
- Parent->Balance = 0;
- return NULL;
- }
- }
- else
- {
- switch (Parent->Balance)
- {
- case -1:
- Parent->Balance = 0;
- return NULL;
-
- case 0:
- Parent->Balance = 1;
- Node = Parent;
- Parent = Node->Parent;
- break;
-
- case +1:
- if (Node->Balance == 1)
- {
- Parent->Balance = 0;
- Node->Balance = 0;
- }
- else
- {
- Parent->Balance = -(Node->Left->Balance == 1);
- Node->Balance = (Node->Left->Balance == -1);
- Node->Left->Balance = 0;
- Rotate_R (Tree, Node);
- }
- Rotate_L (Tree, Parent);
- return NULL;
- }
- }
- }
- return NULL;
- }
-
- /************************************************************************/
- /* */
- /* Search a node */
- /* NULL for not found */
- /* */
- /************************************************************************/
-
- struct AVLNode *
- AVL_SearchNode (struct AVLTree *Tree, struct AVLNode *Node)
-
- {
- struct AVLNode *CurrentNode;
- int CompareResult;
-
- CurrentNode = Tree->Root;
- while (CurrentNode && (CompareResult = Tree->CompareNodes (Node, CurrentNode)))
- {
- if (CompareResult < 0)
- {
- CurrentNode = CurrentNode->Left;
- }
- else
- {
- CurrentNode = CurrentNode->Right;
- }
- }
- return CurrentNode;
- }
-
- /************************************************************************/
- /* */
- /* Init the state info for a traversal. */
- /* */
- /************************************************************************/
-
- void
- AVL_InitTraversal (struct AVLTree *Tree, struct AVLStateInfo *StateInfo)
-
- {
- StateInfo->FromNode = NULL;
- StateInfo->CurrentNode = Tree->Root;
- StateInfo->GoRight = FALSE;
- }
-
- /************************************************************************/
- /* */
- /* Do an inorder traversal of a tree. */
- /* */
- /************************************************************************/
-
- struct AVLNode *
- AVL_InOrder (struct AVLStateInfo *StateInfo)
-
- {
- if (StateInfo->GoRight)
- {
- StateInfo->FromNode = StateInfo->CurrentNode;
- if (StateInfo->CurrentNode->Right)
- {
- StateInfo->CurrentNode = StateInfo->CurrentNode->Right;
- }
- else
- {
- StateInfo->CurrentNode = StateInfo->CurrentNode->Parent;
- }
- }
-
- while (StateInfo->CurrentNode)
- {
- if (StateInfo->FromNode == StateInfo->CurrentNode->Parent)
- {
- if (StateInfo->CurrentNode->Left)
- {
- StateInfo->FromNode = StateInfo->CurrentNode;
- StateInfo->CurrentNode = StateInfo->CurrentNode->Left;
- }
- else
- {
- StateInfo->GoRight = TRUE;
- return StateInfo->CurrentNode;
- }
- }
- else if (StateInfo->FromNode == StateInfo->CurrentNode->Left)
- {
- StateInfo->GoRight = TRUE;
- return StateInfo->CurrentNode;
- }
- else
- /* FromNode == CurrentNode->Right */
- {
- StateInfo->FromNode = StateInfo->CurrentNode;
- StateInfo->CurrentNode = StateInfo->CurrentNode->Parent;
- }
- }
- return NULL;
- }
-